﻿// Decompiled with JetBrains decompiler
// Type: Microsoft.InfoCards.ProcessManager
// Assembly: infocard, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
// MVID: 8E14765A-6610-409A-BA36-099A0642905D
// Assembly location: E:\git\ALLIDA\windll\infocard.exe

using Microsoft.InfoCards.Diagnostics;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security.Principal;

namespace Microsoft.InfoCards
{
  internal class ProcessManager : IDisposable
  {
    private const int WindowsVistaMajorVersion = 6;
    private const string s_OnScreenKeyboardExeName = "osk";
    private const string s_SwitcherExeName = "msswchx";
    private const string s_TcserverExeName = "tcserver";
    private SafeJobHandle m_hJob;
    private List<Process> m_processList;
    private uint m_userSessionId;
    private string m_trustedUserSid;

    public ProcessManager(int userSessionId, string trustedUserSid)
    {
      this.m_hJob = (SafeJobHandle) null;
      this.m_userSessionId = (uint) userSessionId;
      this.m_processList = new List<Process>();
      this.m_trustedUserSid = trustedUserSid;
    }

    internal bool IsConsoleOrVista
    {
      get
      {
        if ((long) this.m_userSessionId != (long) NativeMethods.WTSGetActiveConsoleSessionId())
          return Environment.OSVersion.Version.Major >= 6;
        return true;
      }
    }

    internal bool IsXPTablet
    {
      get
      {
        if (Environment.OSVersion.Version.Major < 6)
          return 0 != NativeMethods.GetSystemMetrics(86);
        return false;
      }
    }

    public void AddProcess(
      SafeNativeHandle hTrustedUserToken,
      ref string trustedUserSid,
      string infocardDesktop,
      uint userProcessId,
      WindowsIdentity userIdentity,
      string fullPath,
      string commandLine,
      bool fUseElevatedToken)
    {
      IntPtr zero = IntPtr.Zero;
      int pid = 0;
      bool success1 = false;
      bool success2 = false;
      RuntimeHelpers.PrepareConstrainedRegions();
      try
      {
        if (this.IsConsoleOrVista && this.m_hJob == null)
        {
          this.m_hJob = Utility.CreateJobObjectWithSdHelper(trustedUserSid);
          if (this.m_hJob == null)
            throw InfoCardTrace.ThrowHelperError((Exception) new Win32Exception(Marshal.GetLastWin32Error()));
        }
        hTrustedUserToken.DangerousAddRef(ref success1);
        IntPtr handle = hTrustedUserToken.DangerousGetHandle();
        IntPtr jobHandle = IntPtr.Zero;
        if (this.IsConsoleOrVista)
        {
          this.m_hJob.DangerousAddRef(ref success2);
          jobHandle = this.m_hJob.DangerousGetHandle();
        }
        if (NativeMcppMethods.CreateProcessAsTrustedUserWrapper(fullPath, commandLine == null ? "" : commandLine, userProcessId, infocardDesktop, userIdentity.Name, this.m_userSessionId, ref handle, ref zero, ref pid, jobHandle, ref trustedUserSid, fUseElevatedToken) != 0U)
          return;
        using (SafeNativeHandle safeNativeHandle = new SafeNativeHandle(zero, true))
        {
          if (!this.IsConsoleOrVista)
            this.m_processList.Add(Process.GetProcessById(pid));
          safeNativeHandle.Dispose();
        }
      }
      finally
      {
        if (success1)
          hTrustedUserToken.DangerousRelease();
        if (success2)
          this.m_hJob.DangerousRelease();
      }
    }

    public void Dispose()
    {
      using (new SystemIdentity(false))
      {
        if (this.IsConsoleOrVista)
        {
          if (this.m_hJob != null)
          {
            this.m_hJob.Dispose();
            this.m_hJob = (SafeJobHandle) null;
          }
        }
        else
        {
          bool flag = false;
          for (int index = 0; index < this.m_processList.Count; ++index)
          {
            Process process = this.m_processList[index];
            if (!process.HasExited)
            {
              try
              {
                if ((long) this.m_userSessionId == (long) process.SessionId)
                {
                  if (string.Compare(process.ProcessName, "osk", StringComparison.OrdinalIgnoreCase) == 0)
                    flag = true;
                  Utility.KillHelper(process);
                }
              }
              catch (InvalidOperationException ex)
              {
              }
            }
          }
          if (flag)
          {
            foreach (Process p in Process.GetProcessesByName("msswchx"))
            {
              if ((long) this.m_userSessionId == (long) p.SessionId)
              {
                if (!p.HasExited)
                {
                  Utility.KillHelper(p);
                  break;
                }
                break;
              }
              p.Dispose();
            }
          }
          this.m_processList.Clear();
        }
      }
      if (!this.IsXPTablet)
        return;
      this.KillTcserverInstancesForInfoCardDesktop();
    }

    private void KillTcserverInstancesForInfoCardDesktop()
    {
      foreach (Process p in Process.GetProcessesByName("tcserver"))
      {
        if (NativeMcppMethods.IsCardSpaceTcserverInstance(p.Id, this.m_trustedUserSid))
          Utility.KillHelper(p);
        p.Dispose();
      }
    }
  }
}
